// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using Microsoft.Data.Sqlite;

namespace SnapObjects.Data.Sqlite
{
    public class SqliteAdoDbDataVisitor : AdoDbDataVisitor
    {
        public SqliteAdoDbDataVisitor(
            SqliteCommand sqlCommand,
            SqliteDataReader sqlDataReader,
            IEnumerable<IAdoDbParameter> parameters,
            IDataContextOptions contextOptions)
            : base(sqlCommand, sqlDataReader, parameters, contextOptions)
        {

        }

        // Workaround Microsoft.Data.Sqlite.SqliteDataReader.GetFieldType() issue
        // when the column's value is null in the first record, 
        // the column's dbtype is always int32.
        protected override IList<DbColumnInfo> CreateColumnSchema()
        {
            var columnSchema = new List<DbColumnInfo>();
            var hasSqliteNullType = false;
            Type columnDBType;

            for (var i = 0; i < _reader.FieldCount; i++)
            {
                columnDBType = _reader.GetFieldType(i);
                if (columnDBType.ToString() == "System.Int32")
                {
                    hasSqliteNullType = true;
                    break;
                }

                columnSchema.Add(new DbColumnInfo(i, _reader.GetName(i), columnDBType));
            }

            if (hasSqliteNullType)
            {
                columnSchema.Clear();
                var schemaTableRecords = ((SqliteDataReader)_reader).GetSchemaTable().Rows;
                for (var i = 0; i < _reader.FieldCount; i++)
                {
                    columnDBType = _reader.GetFieldType(i);
                    if (columnDBType.ToString() == "System.Int32")
                    {
                        columnDBType = (Type)schemaTableRecords[i][12];
                    }

                    columnSchema.Add(new DbColumnInfo(i, _reader.GetName(i), columnDBType));
                }
            }

            return columnSchema;
        }
    }
}
